package reco.db.validation;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import reco.db.Constraint;

public class BetweenConstraintFactory<C extends Comparable<? super C>> extends SimpleConstraintFactory implements DateConstraintFactory,
                NumberConstraintFactory {
    private final C min;
    private final C max;

    public BetweenConstraintFactory(C constraintMin, C constraintMax) {
        super(expectedTypeFor(constraintMin, constraintMax));
        this.min = constraintMin;
        this.max = constraintMax;
    }

    private static Class<?> expectedTypeFor(Object constraintMin, Object constraintMax) {
        checkNotNull(constraintMin, "constraintMin");
        checkNotNull(constraintMax, "constraintMax");
        checkArgument(constraintMin.getClass().equals(constraintMax.getClass()),
                        "min [instance of %s] and max [instance of %s] are of different classess", constraintMin.getClass(), constraintMax.getClass());
        return constraintMin.getClass();
    }

    @Override
    protected <T> Constraint<T> createConstraint() {
        @SuppressWarnings({ "unchecked", "rawtypes" })
        // already validated that C is assignable from T
        final Constraint<T> constraint = (Constraint<T>) new BetweenConstraint(this.min, this.max);

        return constraint;
    }
}
